I've got my Emacs set up to display in "bold, fluo foregound and a dark background underlined by a pink line" (yes, literally that obnoxious) any character which is not part of a list of characters I consider to be acceptable. And it's configured to show any "zero width" character as if it had a width. So any "invisible character" as well as any "invisible zero width character" does appear as a black square, underlined with a pink line.
Sure... For a start I have my scratch buffer showing a few Unicode characters, one trailing spacing character on purpose (to be sure I can see it's highlighted), a zero-width-non-joiner 0x200C and an Hangul filler 0x3164 (may add some from TFA btw). This helps me quickly verify, upon startup, that my setup is working.
I configured all that literally years ago so I don't remember where's what but here's what I've got:
;; probably cargo-culted from somewhere
(update-glyphless-char-display 'glyphless-char-display-control '((format-control . empty-box) (no-font . empty-box)))
;; See https://emacs.stackexchange.com/questions/65108
(set-face-background 'glyphless-char "purple")
And then I've got this too (requires markchars.el):
(markchars-global-mode)
With:
(defface markchars-heavy
'((t :underline "magenta"))
"Heavy face for `markchars-mode' char marking."
:group 'markchars)
It should get you started.
(and, yup, I know it's overkill but I like it that way)
I've got my Emacs set up to display in "bold, fluo foregound and a dark background underlined by a pink line" (yes, literally that obnoxious) any character which is not part of a list of characters I consider to be acceptable. And it's configured to show any "zero width" character as if it had a width. So any "invisible character" as well as any "invisible zero width character" does appear as a black square, underlined with a pink line.
And that for any buffer/file.