Generating abbreviations for strings
Some possible improvement points:


Splitting out functions for word grouping, padding, and word filtering
Removing unnecessary branching
Moving from fold to self-contained recursive functions that require less post processing
Use a HashSet with a StringComparer for filtering


Using these techniques, and avoiding regexes (like my previous answer), we can get a solution that may be easier to reason about:

    open System.Collections.Generic

    let getWords (str:string) =
        let word rev_chars = 
            (rev_chars |&gt; List.rev |&gt; Array.ofList |&gt; String).ToUpper()

        let add_word rev_chars acc = 
            if rev_chars &lt;&gt; [] then (word rev_chars) :: acc else acc

        let rec loop (idx:int) (rev_chars:char list) (acc: string list) prev_lower =
            if idx &lt; str.Length then
                let c = str.[idx]
                let rev_chars, acc =
                    match str.[idx] with
                    | ' '                                      -&gt; []             , (add_word rev_chars acc)
                    | c when Char.IsUpper(c)                   -&gt; [c]            , (add_word rev_chars acc)
                    | c                                        -&gt; (c::rev_chars) , acc
                loop (idx + 1) rev_chars acc (Char.IsLower c)
            else
                let acc = add_word rev_chars acc in List.rev acc

        loop 0 [] [] false

    let pad (str:string) len padchar =
        if str.Length &lt; len then str + String(padchar, (len - str.Length)) else str

    // Filter a list of words, if we can 'afford' it, starting from the back    
    let filterWords (ignoreList:HashSet&lt;string&gt;) charCount words =
        let rec loop revWords acc =
            match revWords with
            | [] -&gt; acc
            | word::revWords when ignoreList.Contains(word) -&gt;
                let getLen = List.fold (fun len s -&gt; len + String.length s) 0            
                let maxLenWithout = (getLen words) + (getLen acc)
                let numOtherParts = List.length revWords + List.length acc
                if maxLenWithout &gt;= charCount &amp;&amp; numOtherParts &gt;= charCount then loop revWords acc
                else loop revWords (word::acc)
            | word::revWords -&gt; loop revWords (word::acc)

        loop (List.rev words) []

    let genAbbr (ignoreList:HashSet&lt;string&gt;) padding charCount (str : string) =
        let words = getWords str |&gt; filterWords ignoreList charCount

        // Given a list of words, generate a sequence of abbreviations
        let rec abbrs before (words: string list) : string seq = seq {
                match words with
                | [] -&gt; ()
                | word::words -&gt;
                    for i = 1 to word.Length do
                        let before = before + word.Substring(0, i)
                        yield before + (words |&gt; List.map (fun w -&gt; w.Substring(0, 1)) |&gt; String.concat "")
                    yield! abbrs (before + word) words }

        (abbrs "" words)
        |&gt; Seq.takeWhile (fun s -&gt; s.Length &lt;= charCount)
        |&gt; Seq.maxBy (fun s -&gt; s.Length)
        |&gt; fun s -&gt;
            match padding with | None -&gt; s | Some padchar -&gt; pad s charCount padchar


To call it:

    let ignored = let h = HashSet&lt;string&gt;(StringComparer.OrdinalIgnoreCase) in h.Add("the") |&gt; ignore; h

    ["The Main Test Company"; "Main Test Company"; "The Main Company"; "The Company"; "Company"; "MainCompany"; "The MainCompany"; "MainTestCompany"; "SomeRX"; "SomeCompanyT"]
    |&gt; List.map (fun w -&gt; w,  (genAbbr ignored None 3 w))