Uiua, 11 bytes
⊕□⊚⍜ₙ⇡2+1⧻.
Nice and short! ⊕ (group) and ⊚ (where) are a great combo for this.
⊕□⊚⍜ₙ⇡2+1⧻. # input string on the right. "abcdefghijklmno"
+1⧻. # length + 1 16
⍜ₙ⇡2 # 2^( range( log_2( that ))) [1 2 4 8]
⊕□⊚ # group into pieces that size {"a" "bc" "defg" "hijklmno"}
⍜ₙ⇡2 means range (⇡) "under" (⍜) logarithm ₙ base 2. ⍜ applies a function, then a second function, and then the inverse of that first function. Here, we apply log_2(x), then range, and then the inverse of log_2(x) which is 2^x.
Literally, ⊕□⊚ does:
# [1 2 4 8]
⊚ # these repeat the naturals: [0 1 1 2 2 2 2 3 3 3 3 3 3 3 3]
⊕□ # group by boxing the chars a b c d e f g h i j k l m n o
# corresponding with indices {"a" "bc" "defg" "hijklmno"}