Rotate brackets until they're balanced
Husk, 7 5 bytes
ṙ¹η◄∫

Try it online!
No loops, no recursion, just a straightforward simple operation. Encodes [ as 1 and ] as -1.
ṙ¹η◄∫
ṙ¹       Rotate the list left by
  η        the (1-based) index
   ◄         of the minimum
    ∫      in the list of cumulative sums
 

This comes from observing that the list of cumulative sums will have a minimum at the point where the most closed brackets are preceding open brackets. By moving all the previous brackets to the end, we can guarantee that there won't be any prefix containing more closed than open brackets.

Previous answer, 7 bytes
Ωȯ¬▼∫ṙ1

Try it online!
Encodes [ as 1 and ] as -1, following HyperNeutrino's idea to use the cumulative sum, but then uses an additional observation:
Since we are working with an equal number of open and closed brackets, the total sum will always be 0. If at any point the string is unbalanced, the cumulative sum at that point will be negative. From this, we can say that a string will be balanced if the minimum of its cumulative sum is exactly 0.
Ω(¬▼∫)ṙ1
      ṙ1    Rotate by 1
Ω           until
   ▼         the minimum
    ∫        of the cumulative sums
  ¬          is 0