Phantom types seem to get used reasonably regularly in a variety of languages for ensuring the safe use of various values (as identifiers, for state transitions and others).
A colleague and I recently found a case where they provided a slightly different benefit. They still helped provide some required type safety, but in this case they also helped to statically associate a value with a generic type parameter, avoiding a runtime lookup and keeping the code succinct using type inference.
This post uses Kotlin, but should be applicable to Java or any other language with generics / parameterised types.