JSFiddle - React, Tailwind, and code Playground

CSS

.row {
  overflow: hidden;
}

.word {
  background: #88F;
  border-radius: 10px;
  border: 3px solid white;
  color: white;
  font-family: sans-serif;
  float: left;
  padding: 3px 12px 3px 8px;
  margin: 1px;
  margin-right: -10px;
}

JavaScript

function subWord( w, p ){
  return w.substr(0,p) + w.substr(p+1);
}

function genNextLevel( P ){ // P: prev/parent level
  var N = {};               // N: next level
  var len = 0;
  for( var pw in P ){ // pw: parent word
    for( var cp = 0; cp < pw.length; cp++ ){ // cp: char pos
      var cw = subWord( pw, cp ); // cw: child word
      if( wo[cw] ){
        len++;
        P[ pw ].leaf = false;
        N[ cw ] = { word:pw, pos:cp, leaf:true };
      }
    }
  }
  return len ? N : null;
}

function traceWord( li, w ){
  var r = [ w ];
  while( li ){
    w = levels[ li ][ w ].word;
    if( !w ) break;
    r.unshift( w );
    li--;
  };
  return r;
}

$(function(){   setTimeout(function(){
  window.wo = {};
  for(var i=0; i < wa.length; i++) wo[ wa[i]] = true;

  window.levels = [];

  var level0 = {};
  for(var i=0; i < 30; i++){
    var w = wa[ Math.floor(Math.random()*wa.length) ];
    level0[ w ] = { word:null, pos:null, leaf:true };
  }
  levels.push( level0 );

  while(true){
    var nl = genNextLevel( levels[ levels.length-1 ]);
    if( ! nl ) break;
    levels.push( nl );
  }

  for( var li = levels.length-1; li >= 0; li-- ){
    var level = levels[ li ];
    for( var w in level ){
      var trace = traceWord( li, w );
      if( trace.length < 2 ) continue;
      //tr( trace.join(' -> ') );
      var $row = $('<div class="row"/>');
      $.each( trace, function(){
         var $word = $('<div class="word"></div>').text( this );
         $row.append( $word );
      });
      $('body').append( $row );
    }
  }

},1000); });


window.wa =...