The general format of all the coloured text is this (with line numbers so I can explain it more easily):
1 | say(6)
2 | #
3 | say(5)
4 | #
5 | text(colour,x,y,lines)
6 | A
7 | B
8 | C
For lines 1 and 3, you can use either say() or reply(). The say()/reply() on line 1 chooses the noise made when the text comes up; use say() to make it sound like a terminal, or reply() to make is sound like a player. Line 3 chooses the position; say() puts it in the centre of the screen, reply() puts it near the player.
text(colour,x,y,lines) is pretty self-explanatory. As PJ said, the colours are:
=purple (despite clearly being pink, not purple). I'm guessing the terminal colour is probably grey, but you can leave it blank and it defaults to grey. Plus if you want a terminal, you may as well just use say(). x and y would choose the position, but the only time I've ever got use out of them made the same text appear twice in a row, so they're not terribly useful. In any case, it's forced into the position chosen on line 3, so you can leave those as zeros. lines is the same as with say() or reply(), but you can only have 1, 2 or 3.
Lines 2 and 4 have to be there for whatever reason; they can't be blank, so I've just filled them with #'s. Lines 6, 7 and 8 are for your text, but all three have to be there even if you only want one line, so again, I filled them with #'s when not needed.
And that's all the tricks I used; it seems that lines 5, 6, 7 and 8 can be whatever you want in the internal VVVVVV scripting language, so
1 | reply(6)
2 | #
3 | say(5)
4 | #
5 | #
6 | text(red,0,0,1)
7 | Words
8 | #
produces the text just fine. You can also use endcutscene() to get rid of the cutscene bars, cutscene() to put them back in, and speak_active and endtext probably do something as well, but I've not found anything terribly useful to do with them other than making the same text appear twice in a row. I'd tried using position(player,above), but that didn't seem to do anything; it'd always use the x,y coordinates or the position as set on line 3, so unfortunately I don't know whether I'll be able to make much use of position(colour,above) either.
As for the reason this all happens, as best as I can tell it all stems from say() or reply() commands with a number of lines greater than 5. These seem to take any say()/reply() commands below them and parse those from the editor script into VVVVVV's internal script before parsing the first say(number>5). This means you can trick the parser into thinking editor text has already been parsed. But I can only break say() commands and not any others, so I can't learn much about other useful commands in VVVVVV's scripting to use, and no matter how large the number in the first say(number>5) is, I couldn't get more than 4 lines of script working, which limits what I can do with things like position(), speak_active and endtext. There's not much point fiddling around with it much more anyway, as if more editor commands are on the way, it'll be pretty redundant soon. Still, I'm surprised about how well this workaround worked; it's surprisingly stable.
Oh, and while I'm bug reporting, if you sit in the room 'Frogger' for too long (the green one with the horizontal warping), the game quits on you; no error message or anything. And it's nothing to do with script tomfoolery either, it happens with an older save of the level without the coloured text too. No idea what's causing that.