Regarding whether a tool is useful in real life, it depends why you need immutability (as that referenced post asks, are you verifying at runtime, or via inspection, or protecting against malicious code, or just ensuring your own code is immutable?). The simplest assurance that a class is immutable if you're manually reviewing it is that all field writes occur only in the constructor or that all fields are final (or both).
But that's still limited because "final Object x" assures that your reference doesn't change but not that the referenced object doesn't change. As Adam eludes to, if that's a list, the underlying list could change, which could cause thread problems in your (otherwise immutable) class. And if you used the value in the list to determine your hash code (you use x.hashCode() as part of generating your own hash code) then your hash code would change violating other rules (so an immutable view of a list isn't even sufficient).
If your immutable class wouldn't be affected by changes to a held object, then it may be OK for your purposes.
Checking at runtime has to be time/depth/scope limited so can't be perfect. Those tools (or any similar runtime approach) have some use, but it really depends on why you need to determine immutability. If you can spec immutability as part of an API requirement, detect violations of that rule (e.g. hashCode of object changes), and throw an exception when they change, then you don't need to detect it yourself. Or trust your callers. If you're trying to write the immutable class, those tools don't help at all. If you're really looking for thread safety, immutability is, unto itself, an insufficient answer.
It's not a satisfying answer to this question (which is a good one), but I think in most cases it ends up being the wrong question to ask if you look at the problem more closely.