I did start with the techniques, then checked if the languages supported them. My ideas are a lot clearer than you seem to think. Thanks to you and the others, I now have resolved my confusion: "OO" doesn't technically mean anything significant, but nevertheless carries a strong emotional load (positive or negative, depending on the reader). That tends to end useful discussion and to encourage religious flame-wars. I now consider "OO" taboo, along with sentences like "just a tool". I now believe that most programmers did fall in the trap I spoke of in my original post, but this trap appears to be less obvious than I thought.

Now about what implements what:

Coupling reduction is implemented by encapsulation. There's no other way. Any technique that reduces coupling is a form of encapsulation. Any language that supports coupling reduction supports encapsulation.

Encapsulation is supported by 3 features: functions, modules, and classes. Let's not talk about functions, whose presence don't differentiate. So, to support encapsulation (and therefore coupling reduction), a language needs either modules or classes.

Code reuse is achieved with functions and abstraction as you defined it. I don't know any other way, short of writing a DSL or using a whole program. As before, let's not talk about functions themselves. Therefore, any language that supports code reuse supports abstraction.

Abstraction means I can interact the same way with two "things" if they are of the same type. Well, I think that by "guy", you meant "something with embedded behaviour", and not just dead data, like integers or arrays. Such a thing is necessarily a closure. Closures can be achieved by 3 mechanisms: subtype polymorphism (interfaces, mixins…), duck typing, and first class functions (which are isomorphic to duck typed mono-method objects). I said "parametric polymorphism" earlier, but it isn't actually needed. So, to supports abstraction (and therefore code reuse), a language must have either subtype polymorphism or first class functions.

Now Back to OO.

To support OO, a language must support encapsulation and abstraction. I've established that it's the same as saying that it must support coupling reduction and code reuse. And intuitively, a language that doesn't support either of them isn't worth using. Therefore any modern language should support OO.

Now, supporting OO is not the same as being OO. To be OO in my book, a language must actually strongly encourage the frequent use of encapsulation and abstraction. As it happens, most modern languages do.

Almost all have either modules or classes. And when they do, they strongly encourage you to use them systematically, if they do not flatly mandate it like Java.

Likewise, almost all have either subtype polymorphism, duck typing, or first class functions. And when they do, they strongly encourage their frequent use.

Which means that almost every modern language strongly encourages the frequent use of all the necessary OO features. In other words, almost every modern language is OO. C++ and Java are OO because of their classes and subtype polymorphism. Ocaml and Haskell are OO because of their module system and their first class functions. You probably didn't intend to qualify those last two as OO (I don't, and they don't claim to be), but they fit your definition nevertheless.