No strings attached!
Retina, 21 bytes

+`(.)(?!\1)(?i)\1

^$


Try it online!

Like flawr's solution, this just repeatedly deletes adjacent uppercase/lowercase pairs and then checks whether the result is empty or not.

As for how one matches an uppercase/lowercase pair:

(.)     # Match and capture a letter.
(?!\1)  # Ensure that the next character is not the same, to avoid matching
        # "aa" and "AA".
(?i)    # Turn on case-insensitivity.
\1      # Match the backreference. In .NET, when using case insensitivity,
        # backreferences also get case-insensitive, so this *can* still match
        # iff the cases of the two letters are different.