Here's my submission. There are two programs: the first builds a set
of puzzles from a decent word list I found on line. Files like
/usr/dict/words have too many obscure words. The second is a (very)
simplistic game interface.

A "puzzle" is just a string of six or more 3-6 letter words, sorted by
length. The output of the first program is just one line per puzzle,
with the words separated by colons. The words are ROT13 encoded. The
puzzles.rb program generates 905 different puzzles.

Bob Showalter

---------- puzzles.rb ----------

# puzzles.rb
# generate puzzles for use by wordblend.rb program
#
# usage: ruby puzzles.rb >puzzles.dat

require 'open-uri'
require 'yaml'

# these urls point to text files with lists of 2000 commonest
# English word "families", including plurals and other forms.
# this ends up generating reasonably good puzzles.
URIS = %w{
  http://www1.harenet.ne.jp/~waring/vocab/wordlists/full1000.txt
  http://www1.harenet.ne.jp/~waring/vocab/wordlists/full2000.txt
}

# minimum number of words necessary to form a puzzle
MIN_SIZE = 6

# define some helper functions
class String

  # returns string with characters in sorted order
  def sort
    split(//).sort.join
  end

  # returns true if s is a subword of the string. both
  # the string and s must be sorted!
  def subword?(s)
    i = j = 0
    while j < s.length
      i += 1 while i < length and self[i] != s[j]
      i < length or return false
      j += 1
      i += 1
    end
    true
  end

end

# grab the 3-6 letter words from word lists. sort each word by
# character (e.g. 'test' becomes 'estt'), and then accumulate
STDERR.puts "Fetching words..."
words = Hash.new {|h,k| h[k] = []}
URIS.each do |uri|
  open(uri) do |f|
    f.read.split.select {|w| w.length >= 3 and w.length <= 6}.each do |word|
      word.upcase!
      sword = word.sort
      words[sword] << word
    end
  end
end

# find puzzles by looking at which sorted words are contained in
# other six-character sorted words.
STDERR.puts "Finding puzzles..."
n = 0
words.keys.select {|w| w.length == 6}.each do |key|
  puzzle = words.select {|ssub, subs| key.subword?(ssub)}.collect {|a|
a.last}.flatten.sort_by {|w| "#{w.length}#{w}"}
  next if puzzle.size < MIN_SIZE
  puts puzzle.join(':')
end

---------- wordblend.rb ----------

# wordblend.rb
# simplistic Word Blend puzzle game
# uses puzzles.dat file created by separate puzzles.rb program

class String
  def rot13
    tr 'A-Za-z', 'N-ZA-Mn-za-m'
  end
end

class Puzzle

  attr_reader :words, :letters, :board

  def self.pick
    @@puzzles ||= IO.readlines('puzzles.dat')
    new(@@puzzles[rand(@@puzzles.size)].chomp.rot13.split(':'))
  end

  def initialize(words)
    @words = words
    scramble
    @board = words.collect {|w| w.gsub(/./, '-')}
  end

  def scramble
    @letters = words.last.split(//).sort_by {rand}.join
    scramble if words.include? @letters
  end

  def help
    puts "Enter 'Q' to give up, 'S' to scramble letters"
  end

  def play
    help
    turn while board != words
    puts board
  end

  def turn
    puts board
    puts
    puts letters
    while true
      print "? "
      guess = gets.strip.upcase
      if guess == ''
        help
        redo
      end
      if guess == 'S'
        scramble
        puts letters
        redo
      end
      @board = words.dup if guess == 'Q'
      i = words.index(guess) and board[i] = guess
      break
    end
  end

end

# play a random game
p = Puzzle.pick
p.play