Yet another take. You could always select 'level' as well, say after the 'id' and see the word's position in the title if you wished.
This uses the with clause to just set up the test data. Then for each row, "loop" through each word using connect by where the word's characters are followed by a space or the end of the line. It loops the number of occurrences of a space in the line plus one for the last word.
with tbl(id, title) as (
select 1, 'extract words' as title from dual union all
select 2, 'words in a phrase' from dual
)
select id, regexp_substr(title, '(.*?)( |$)', 1, level, NULL, 1) as words
from tbl
connect by level <= regexp_count(title, ' ') + 1
and prior id = id
and prior sys_guid() is not null;
ID WORDS
---------- -----------------
1 extract
1 words
2 words
2 in
2 a
2 phrase
6 rows selected.