That's a cool idea. How I'd handle it is through a single string variable containing the poem, then use DOM replacement macros (<<replace>> in SugarCube) to update the output. I'd store the word bank itself in an array.
Here's a rough example of how something like that might look in SugarCube 2. Note that you can install SugarCube 2 in Twine 1 if you want to stick with 1.
::StoryInit
<<set $poem to ''>>
<<set $wordBank to [
'hello',
'how',
'the',
'sky',
'blah',
'feels'
]>>
::main
<div id='poem'>$poem</div>
<div id='word-bank'><<include 'bank'>></div>
::bank
<<for _i to 0; _i < $wordBank.length; _i++>>\
<<capture _i>>\
<<link $wordBank[_i]>>
<<addword $wordBank[_i]>>
<</link>>
<</capture>>\
<</for>>
<<button 'Add Line Break'>>
<<addbreak>>
<</button>>\
::widgets [widget nobr]
<<widget 'addword'>>
<<set _word to $args[0]>>
<<set _del to $wordBank.indexOf(_word)>>
<<if $poem is ''>>
<<set $poem to _word>>
<<else>>
<<set $poem to $poem + ' ' +_word>>
<</if>>
<<run $wordBank.deleteAt(_del)>>
<<if $wordBank.length < 1>>
<<replace '#word-bank'>>\
<<link 'Again'>>
<<run Engine.restart()>>
<</link>>\
<</replace>>
<<else>>
<<replace '#poem'>>$poem<</replace>>
<</if>>
<<replace '#word-bank'>><<include 'bank'>><</replace>>
<</widget>>
<<widget 'addbreak'>>
<<set $poem to $poem + '\n'>>
<<replace '#poem'>>$poem<</replace>>
<</widget>>
Then in CSS:
#word-bank {
float: right;
margin: 2em;
margin-top: 10%;
padding: 1em;
border: 2px #eee solid;
height: 20em;
width: 10em;
}
I'm not sure if there's an easy way to accomplish this in Harlowe or Sugarcane; the <<for>> macro and the <<capture>> macro are pretty important here, and Sugarcane lacks both. It might work with some modification in Harlowe.