In general: Don’t use columns, avoid unreasonably short \hsize
es when typesetting paragraphs. Marco already gave you the answers that may get you a typographically good result.
If this still doesn’t satisfy you need and you cannot simply rewrite the text using shorter words, you might as well consider turning to the dark side™: You can resort to letter spacing, just as newspapers and other junk typography does. The following code -- which I adapted from the glorious chickenize package (see its manual for documentation) -- lets you define environments for different values.
Save this snippet as lsp_adj.lua
:
thirddata = thirddata or { }
thirddata.lsp_adj = { }
local lsp_adj = thirddata.lsp_adj
lsp_adj.callbacks = { }
local nodecopy = node.copy
local nodeid = node.id
local nodeinsert_before = node.insert_before
local nodenew = node.new
local nodetraverse_id = node.traverse_id
local nodesinstallattributehandler = nodes.installattributehandler
local nodestasksappendaction = nodes.tasks.appendaction
local nodestasksdisableaction = nodes.tasks.disableaction
--- For tests later.
local GLYPH_NODE = nodeid"glyph"
local DISC_NODE = nodeid"disc"
lsp_adj.new_callback = function (id, stretch)
--- Prepare a glue; this will be copied all over.
local letterspace_glue = nodenew(nodeid"glue")
local letterspace_spec = nodenew(nodeid"glue_spec")
letterspace_spec.width = tex.sp"0pt"
letterspace_spec.stretch = tex.sp(stretch)
letterspace_glue.spec = letterspace_spec
--- We’re gonna need a nobreak style penalty too. Else there will be
--- line breaks inside words.
local letterspace_pen = nodenew(nodeid"penalty")
letterspace_pen.penalty = 10000
--- Generate a callback; note the order of arguments.
local cbk = function (_, _, head)
for glyph in nodetraverse_id(GLYPH_NODE, head) do
--- Insert glue between glyphs and ligatures.
local prev = glyph.prev
if prev and prev.id == GLYPH_NODE or prev.id == DISC_NODE then
local g = nodecopy(letterspace_glue)
nodeinsert_before(head, glyph, g)
--- Don’t allow breaks here.
nodeinsert_before(head, g, nodecopy(letterspace_pen))
end
end
return head
end
--- Registering a callback requires some verbosity in Context.
--- But it’s well worth it ...
local cbk_id = "lsp_" .. id
lsp_adj.callbacks[id] = nodesinstallattributehandler{
name = cbk_id,
namespace = thirddata.lsp_adj,
processor = cbk,
}
nodestasksappendaction(
"processors",
-- This one is for users according to node-tsk.lua.
"before",
"thirddata.lsp_adj.callbacks." .. id
)
nodestasksdisableaction(
"processors",
"thirddata.lsp_adj.callbacks." .. id
)
end
And test it with this code:
\ctxloadluafile{lsp_adj.lua}{}
\dontcomplain
\setuplayout[middle]
\setuplayout[backspace=1cm,topspace=1cm]
\unprotect
%%% Firstly, set some grotesquely unesthetic default.
\newdimen\letter_space_stretch \letter_space_stretch=2pt
\def\defineletterspace{\dodoubleempty\do_define_letter_space}
\def\do_define_letter_space[#1][#2]{%
\begingroup
\edef\id{#1}%
\ifsecondargument
\ctxlua{
thirddata.lsp_adj.new_callback(\!!bs\id\!!es, \!!bs#2\!!es)
}%
\expandafter\gdef\csname start\id\endcsname{%
\ctxlua{
nodes.tasks.enableaction(
\!!bs processors\!!es,
\!!bs thirddata.lsp_adj.callbacks.#1\!!es
)
}%
}%
\expandafter\gdef\csname stop\id\endcsname{%
\ctxlua{
nodes.tasks.disableaction(
\!!bs processors\!!es,
\!!bs thirddata.lsp_adj.callbacks.#1\!!es
)
}%
}%
\fi
\endgroup%
}
\protect
%%% Now we can define our environments for testing. Note that this is
%%% no module so you won’t get corresponding setups.
\defineletterspace [smalllsp] [.5pt]
\defineletterspace [mediumlsp] [1pt]
\defineletterspace [biglsp] [2pt]
\starttext
%%% For reference: typeset the demo text without letterspacing.
\startcolumns[n=4]
\input knuth
\stopcolumns
\hairline
\startsmalllsp
\startcolumns[n=4]
\input knuth
\stopcolumns
\stopsmalllsp
\hairline
\startbiglsp
\startcolumns[n=4]
\input knuth
\stopcolumns
\stopbiglsp
\hairline
\startmediumlsp
\startcolumns[n=4]
\input knuth
\stopcolumns
\stopmediumlsp
\stoptext
The result won’t please esthetically but depending on the letterspacing factor it may fulfill your constraints.

\hyphenation
commands. Can you give a real example of a problematic word?