UPROPERTY tagging - indeed, pretty much everything does need this, but nothing actually seems to check whether you're getting it right. You can easily add a UObject * , fail to tag it as a UPROPERTY, and now stuff will go wrong. This is what I mean about having to be extra careful. If you get it wrong, you'll never know, until things get GC'd prematurely and it won't be obvious why.
Capturing UObject pointers - in a lambda capture list, I mean. These don't participate in the GC mechanism. You have to store a copy of the pointer in a TWeakObjectPtr or TStrongObjectPtr and capture that instead. Again, nothing actually enforces this, so you just have to be very careful to do it.
UObjects outside the game thread - had this on a recent project where there was a background thread retrieving stuff using a REST API. The data was related to some thing or other that was configured in the editor, so one reasonable-sounding thing to do is hand the relevant UObject * to the thread and have it handle everything. But this isn't valid, because the GC relies on UObject pointers only being manipulated by the game thread. But - and the reader may sense a theme developing here - nothing actually checks whether you're doing this.
TSharedPtr - TSharedPtr is reference counted, so you can't have cycles in your pointer graph. This isn't UE specific (std::shared_ptr suffers from exactly the same problem), it's just another thing that can go wrong that nothing checks for. And it's hard to spot, because there's no built-in debugging features for it.
And regarding tagging TSharedPtrs with the correct multithreading mode, UE5 is multithreaded out of the box as it has separate rendering and game threads, and TSharedPtr is an obvious way to share data between them. But if you do that, you need to specify you want the multithreading-friendly TSharedPtr! (This is a particular pitfall for programmers familiar with std::shared_ptr, of which TSharedPtr is supposedly the equivalent, because std::shared_ptr is multithreading-safe by default.) Anyway, we've had this problem on 2 separate projects, and it wasn't easy to track down in either case. And I'm sure I don't need to specify whether anything checks for this situation.
Anyway, niche or not, I've no idea. I'm no UE expert, just somebody that's done a lot of this stupid C++ crap and helped out on several UE4 and UE5 projects that needed some bugs fixing. And it was just a bit noticeable to me how much the same old C++ stuff (that I've been dealing with for years) was still much in evidence.