Here is my solution. It is my first Ruby program. I was able to get two
of the extra credit with virtually no work. I had snaking already
because I generated the snaked answers before eliminating the ones that
weren't a straight line. I had an alternative output format because I
was using it to debug my code as I went along before I wrote the code
to generate the answer grid. Using the sample input set, here is my
output:

+++R+R++++
++++U+++++
ROCKSB++++
++K+++Y+++
+S+++++++M
+++++++DAN
+++++++T++
+++ND+Z+++
++++A+++++
YBUR++++++

RUBY
(3,0)(4,1)(5,2)(6,3)
(5,0)(4,1)(5,2)(6,3)
(3,9)(2,9)(1,9)(0,9)
ROCKS
(0,2)(1,2)(2,2)(3,2)(4,2)
(0,2)(1,2)(2,2)(2,3)(1,4)
DAN
(7,5)(8,5)(9,5)
(4,7)(4,8)(3,7)
MATZ
(9,4)(8,5)(7,6)(6,7)

The coordinates in the output set are 0-based x,y originating from the
upper-left corner.

-Ben

require "enumerator"

class Point
  attr_reader(:x, :y)
  def initialize(x, y)
    @x = x
    @y = y
  end
  def to_s
    "(#{@x},#{@y})"
  end
  def adj?(p)
    ((@x - p.x).abs <= 1) & ((@y - p.y).abs <= 1) & !(self == p)
  end
  def -(p)
    Point.new(@x - p.x, @y - p.y)
  end
  def ==(p)
    (@x == p.x) & (@y == p.y)
  end
end

class Array
  def diff
    return to_enum(:each_cons, 2).map{|a,b| a-b}
  end
  def same?
    return false if length < 1
    return true if length == 1
    return to_enum(:each_cons, 2).all? {|a,b| a==b}
  end
end

def findletter(puzzle, c)
  locations = []
  puzzle.each_with_index do |line, y|
    line.split(//).each_with_index do |letter, x|
      locations << Point.new(x, y) if letter == c
    end
  end
  return locations
end

def getletters(puzzle, term)
  term.split(//).map{|c| findletter(puzzle, c)}
end

def mixarrays(arr)
  return [] if (arr.empty?)
  return arr.first.zip if (arr.length == 1)

  temp = []
  head = arr.first
  tail = arr.slice(1, arr.length-1)
  head.each do |x|
    mixarrays(tail).each do |y|
      temp << [x] + y
    end
  end
  return temp
end

def connectedword(word)
  return false if word.length < 1
  return true if word.length == 1
  return word.to_enum(:each_cons, 2).all? {|a,b| a.adj?(b)}
end

def showpoints(term, points)
  puts term
  points.each {|x| print x, "\n" }
end

def answergrid(puzzle, points)
  answer = puzzle.map {|line| line.gsub(/./, '+')}
  points.flatten.each do |p|
    answer[p.y][p.x] = puzzle[p.y][p.x] if p.kind_of?(Point)
  end
  return answer
end

puzzle = []
while (line = gets.chomp) != ''
  puzzle << line
end
terms = gets.chomp.upcase.split(/\s*\,\s*/)

terms_words = terms.map{|term|
  [term, mixarrays(getletters(puzzle, term))]}

terms_connectedwords = terms_words.map{|term, words|
  [term, words.select {|word| connectedword(word)}]}

terms_samediffconnectedwords = terms_connectedwords.map{|term, words|
  [term, words.select {|word| word.diff.same?}]}

answerkey = terms_connectedwords

puts
puts answergrid(puzzle, answerkey)

puts
answerkey.each {|term, words| showpoints(term, words) }

Ruby Quiz wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz until
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
>
> http://www.rubyquiz.com/
>
> 3.  Enjoy!
>
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps everyone
> on Ruby Talk follow the discussion.  Please reply to the original quiz message,
> if you can.
>
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>
> by Daniel Finnie
>
> Today's quiz would've been most useful in elementary school, where over half of
> the homework assignments were word search puzzles. The concept of these puzzles
> is simple enough that an elementary school student could understand it:  given a
> box of letters, find a line containing the letters of a specified word in order.
>
> For example, find the words ruby, dan, rocks, and matz in the following text:
>
> 	U E W R T R B H C D
> 	C X G Z U W R Y E R
> 	R O C K S B A U C U
> 	S F K F M T Y S G E
> 	Y S O O U N M Z I M
> 	T C G P R T I D A N
> 	H Z G H Q G W T U V
> 	H Q M N D X Z B S T
> 	N T C L A T N B C E
> 	Y B U R P Z U X M S
>
> The correct answer in the correct output format:
>
> 	+ + + R + + + + + +
> 	+ + + + U + + + + +
> 	R O C K S B + + + +
> 	+ + + + + + Y + + +
> 	+ + + + + + + + + M
> 	+ + + + + + + D A N
> 	+ + + + + + + T + +
> 	+ + + + + + Z + + +
> 	+ + + + + + + + + +
> 	+ + + + + + + + + +
>
> Notice that the words can go backwards and diagonally, and can intersect one
> another. Searching is case insensitive.
>
> The word search solver should accept input entered by the user after running the
> program, i.e., not exclusively through STDIN or a file, by entering the puzzle
> line by line, pressing return after each line. A blank line indicates the end of
> the puzzle and the start of the comma separated words to find. The following
> example shows how a user would enter the above puzzle, with descriptive text
> from the program removed.
>
> 	$ ./wordsearch.rb
> 	UEWRTRBHCD
> 	CXGZUWRYER
> 	ROCKSBAUCU
> 	SFKFMTYSGE
> 	YSOOUNMZIM
> 	TCGPRTIDAN
> 	HZGHQGWTUV
> 	HQMNDXZBST
> 	NTCLATNBCE
> 	YBURPZUXMS
>
> 	Ruby, rocks, DAN, matZ
>
> Now, by itself, this quiz is fairly simple, so I offer an additional challenge.
> Write a beautiful, extensible, and easily-modifiable program without looking at
> the extra credit before starting. When you're done, try implementing extra
> credit options using less than 5 or 6 (reasonable) lines of code.
>
> 	* An output format superior to the one given. The output format given
> 	  should remain the default unless both formats don't differ on a
> 	  textual basis. That should sound cryptic until pondered, I can't
> 	  give too much away!
> 	* Allow for "snaking" of answers, in other words, the letters
> 	  composing a word don't have to be in a straight line.
> 	* An option to give a hint, i.e., "The word ruby traverses the bottom
> 	  left and bottom right quadrants."
> 	* Decide what to do with accented letters.
> 	* Allow for wildcard letters.