> there is no other first-class language feature common to all the self-described "functional" languages.
This line of speech usually serves to corner FP in a self-contradicting definition that can be wrestled with, and it is really aggravating.
Functional programming as a concept is well defined, and it's not merely "first-order functions". The reason why many functional languages don't have the same feature set is that programming languages are works of engineering, and that the essence of engineering is to make tradeoffs.
For instance, F#, a functional language, has many non-functional bits, because the goal pursued was to bring FP to .net, and they made sensible choice to promote interop above functional purity.
Likewise, most people doing FP with Lisp in the early days still used mutable variables, because they were limited by the machines they had.
Another example is the ability to perform all kinds of side-effects in many FP languages (Erlang, Clojure, etc.). That doesn't mean FP practicioners are totally fine with having side-effects. It means that totally separating side-effects from code in a general-purpose programming language is not always easy, and that in the interest of having useful projects, sometimes this goal is set aside. On the other hand, programs running on more limited runtimes (eg. Elm in browsers) achieve it completely.
It is really a pity that so many people can't or don't want to acknowledge the nature of engineering work, and hold imperfections against the creators, or the concepts they try to implement.