The Art of Word Shaping

Vim, 44 42 bytes

qqy$P0xjf1"_xP{@qq@q:s/0/ /g^M:s/,/^V^M/g^M{D

Saved 2 bytes thanks to @DjMcMoylex!

Here, the ^M is a literal newline, and the ^V is CTRL-V

Takes the input in this format:

PPCG
00100,01010,10001,01010,00100

Disclaimer: If the string is longer than ~40 chars long, your computer might run out of ram.

Explanation:

qq             @qq@q                            # Start recording a recursive macro.
  y$P0x                                         # Duplicate the string and cut out the first character
       jf1"_xP{                                 # Find the first 1, and replace it with the cut character from the string.
                                                # Now we have replaced all the 1's with their respective character, but we still have the array in the original format, and we have the string massivly duplicated at the first line, so we need to clean it up:
                    :s/0/ /g^M                  # Replace all 0's with a space
                              :s/,/^V^M/g^M     # Replace all ,'s with a newline. The ^V acts like a backslash, it escapes the newline so that the command isn't run too soon
                                           {D   # Delete the first line

Here's a gif of me "running" the "program":

Me typing the keys


JavaScript ES6, 67 53 50 49 bytes

Saved 3 bytes thanks to @ETHproductions Saved 1 more thanks to @Neil

(a,b,i)=>a.replace(/./g,c=>+c?b[++i]||b[i=0]:' ')

f=
(a,b,i)=>a.replace(/./g,c=>+c?b[++i]||b[i=0]:' ')

G=_=>h.innerHTML = f(`00100
01010
10001
01010
00100`,z.value)
h.innerHTML = G()
<input id=z oninput="G()" value="PPCG"></input>
<pre id=h>

Old code before I knew that string matrices are a valid input format:

(a,b)=>a.map(c=>c.map(d=>d?b[i++%b.length]:' ').join``,i=0).join`
`

f=
(a,b)=>a.map(c=>c.map(d=>d?b[i++%b.length]:' ').join``,i=0).join`
`

G=_=>h.innerHTML = f([[0,0,1,0,0],[0,1,0,1,0],[1,0,0,0,1],[0,1,0,1,0],[0,0,1,0,0]],z.value)
h.innerHTML = G()
<input id=z oninput="G()" value="PPCG"></input>
<pre id=h>


Retina, 41 33 bytes

0

+1`(.)(.*)(\D+)1
$2$1$3$1
A1`

Try it online!

The input string is given on the first row of the input, followed by the matrix. Since Retina has no concept of lists (or really anything except strings), there are no separators in the binary matrix except for linefeeds to separate rows.

Explanation

0

Turns zeros into spaces.

+1`(.)(.*)(\D+)1
$2$1$3$1

Repeatedly replace the first 1 with the first character of the input string while also rotating that character to the end of the input string. This takes care cases where there are more 1s than characters in the input string.

A1`

Discard the first line, i.e. the input string.