So in pragmatic terms, enabling/disabling "extensions" lets you prevent some unnecessary processing loads during compilation.
Obviously one can do everything in "vanilla" (no-"extensions") Haskell just like one could express everything in raw Lambda Calculus. Syntax sugars as always allow for reducing patterns of verbosity --- those provided by "extensions" tend to be such patterns-of-verbosity that don't always occur in-all-projects-all-the-time, just in enough-projects-much-of-the-time.
Most of the aversion to them seems kneejerk "but my other language had another (or none at all) approach to this" --- never understood the strong opinions about GHC extensions. "Other-language" typically also delights in a culture of repetetively verbose syntax itself and no such APIs to hack new language constructs into the compiler in a plug-and-play manner (without forking).
And yes one can enable these via cabal file or GHC -X flags, but there's something to be said for per-module pragmas: they only activate where needed, and it aids the code reader as to what non-vanilla syntactic constructs are used in the-module-at-hand.
If you think there are dozens then I challenge you to name a few ...
(I can't, off the top of my head, think of any but I don't deny there may be some.)
Haskell code with any extensions enabled is pretty much always compatible with Haskell code with any other extensions enabled.
(I only said "pretty much" to hedge my bets. I literally can't think of any case where extensions could make your code incompatible with other code across a module boundary.)
I’m aware there are other compilers but basically everyone uses GHC. So all these things that have to be turned on because they’re not “compatible“ with all the other compilers that no one else uses just add complexity for new users (and I suppose current users.)
Edit: I guess not useless, but over time rendered as anti-features