> OOP has lots of well-known unique characteristics such as inheritance, dynamic dispatch, polymorphism, encapsulation, etc...
OO just means that you have a semantic entity, the object, which contains data and to which you associate code. Your main tool to work with is this object; just like in FP your main tool to work with is the function to which you associate data through closures and currying. Likewise, in logic programming your main tool is the constraint. And these aren't relevant to the language. You can do both OO and FP in most mainstream languages.
> dynamic dispatch
is just allowing to associate a different implementation to the same function name. Every languages that have some kind of function pointer allow this.
> polymorphism
is in almost every language, including FP.
data Tree a = Empty | Node a (Tree a) (Tree a)
is polymorphism. C++ templates are polymorphism. Rust traits are polymorphism.
> message-passing
is only relevant if you adhere to Alan Kay's vision of objects. I personally don't (even if the guy coined the term).