##Python 2.7, 353 bytes
Python 2.7, 353 bytes
Unfortunately, I can't test it with the actual w.txt file ATM because QPython for Android can't seem to handle file I/O. It worked with data I copied and pasted though.
###Part 1, 76 bytes
Part 1, 76 bytes
h=lambda s:({c:s.count(c)for c in s if c.isalnum()},map(len,s[:-1].split()))
In: 'Hi there.'
Out: {'H':1, 'i':1, 't':1, 'h':1, 'e':2, 'r':1}, (2, 5)
so, a list containing:
a hashmap with the histogram
a list of letter counts
###Part 2, 277 bytes import itertools as i m=lambda c:' '.join([s for s in i.product(*[[w for w in open('w.txt')if len(w)==length]for length in c[1]])if sorted(''.join(s))==sorted(sum([[k.lower()]*n for k,n in c[0].items()],[]))and s[0][0]==filter(str.isupper,c[0])[0].lower()][0]).capitalize()+'.'
Part 2, 277 bytes
import itertools as i
m=lambda c:' '.join([s for s in i.product(*[[w for w in open('w.txt')if len(w)==length]for length in c[1]])if sorted(''.join(s))==sorted(sum([[k.lower()]*n for k,n in c[0].items()],[]))and s[0][0]==filter(str.isupper,c[0])[0].lower()][0]).capitalize()+'.'
I'm really glad I managed to make it 100% pure functional. Not sure if that helps with the actual golfing, but I certainly got the obfuscation part right :D Here's A more human friendly version of pt. 2 (exactly the same flow, but with variable names):
from itertools import product
def matching(counts):
histo, word_lengths = counts
first_letter = filter(str.isupper, histo)[0].lower()
letters_nested = [ [char.lower()]*count for char, count in histo.items() ]
letters = sum(letters_nested, [])
word_options = [[word for word in open('w.txt') if len(word)==length] for length in word_lengths]
sentences = product(*word_options)
valid = [sentence for sentence in sentences if sorted(''.join(sentence))==sorted(letters) and sentence[0][0]==first_letter]
return ' '.join(valid[0]).capitalize()+'.'